package com.edu.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.edu.exception.FileException;
import com.edu.repository.FileRespository;
import com.edu.service.FileService;
import com.edu.util.FileHelper;
import com.edu.util.IOHelper;
import com.edu.util.ZFilenameUtils;
import com.edu.vo.FileVO;
import com.edu.vo.SimpleTree;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Service 层 实现
 *
 * @author Administrator
 */
@Service
public class FileServiceImpl implements FileService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${prop.root}")
    private String root;

    @Autowired
    private FileRespository fileRespository;

    /**
     * 创建文件 (支持创建多级目录) 1. 文件名不能含有特殊字符 2. 文件名不能与当前的文件或文件夹重名 3. 文件名必须带有后缀
     * 如果不符合要求，抛出FileException
     *
     * @param dir
     * @param name
     * @throws IOException
     * @throws FileException
     */
    @Override
    public void createDocument(String name) throws IOException, FileException {
        // 文件名不能为空的校验应写在controller层
        // 验证文件名合法性
        if (!ZFilenameUtils.isValidDocName(name)) {
            throw new FileException(FileException.NAME_ILLEGAL);
        }
        // 判断是否重名
        //String parent = ZFilenameUtils.concat(root, dir);
        String fullName = ZFilenameUtils.concat(root, name);
        logger.debug(name);
        if (ZFilenameUtils.isRepeatName(fullName)) {
            throw new FileException(FileException.FILE_ALREADY_EXISTS);
        }
        File file = new File(fullName);
        fileRespository.createDocument(file);
    }

    /**
     * 创建目录 (支持创建多级目录) 1. 文件名不能含有特殊字符 2. 文件名不能与当前的文件或文件夹重名 如果不符合要求，抛出FileException
     *
     * @param dir
     * @param name
     * @throws IOException
     * @throws FileException
     */
    @Override
    public void createDirectory(String name) throws IOException, FileException {
        if (!ZFilenameUtils.isValidDirName(name)) {
            throw new FileException(FileException.NAME_ILLEGAL);
        }
        // 判断是否重名
        //String parent = ZFilenameUtils.concat(root, dir);
        String fullDir = ZFilenameUtils.concat(root, name);
        if (ZFilenameUtils.isRepeatName(fullDir)) {
            throw new FileException(FileException.FILE_ALREADY_EXISTS);
        }
        // 创建目录

        File file = new File(fullDir);
        fileRespository.createDir(file);
    }

    @Override
    public void deleteFile(String name) throws FileException, IOException {
        String fullDir = ZFilenameUtils.concat(root, name);
        File file = new File(fullDir);
        fileRespository.deleteFile(file);
    }

    @Override
    public void renameFile(String name, String rename) throws IOException, FileException {
        logger.debug(rename);
        String sourceName = ZFilenameUtils.concat(root, name);
        String targetName = ZFilenameUtils.concat(root, rename);
        if (ZFilenameUtils.isRepeatName(targetName)) {
            throw new FileException(FileException.FILE_ALREADY_EXISTS);
        }
        //FileHelper.reName(rename, new File(fullName));
        File source = new File(sourceName);
        File target = new File(targetName);
        fileRespository.renameFile(source, target);
    }


    @Override
    public void downloadFile(String name) {
        // TODO Auto-generated method stub

    }

    @Override
    public List<FileVO> enterDirectory(String dir) throws FileException {
        List<FileVO> list = new ArrayList<>();

        logger.debug("{}", dir == null);
        logger.debug(root);
        String dirName = ZFilenameUtils.concat(root, dir);
        logger.debug(dirName);
        File file = new File(dirName);
        // 判断是文件还是目录
        if (file.exists() && file.isDirectory()) {
            list = fileRespository.getDirContent(file);
        } else {
            logger.debug("文件不存在或不是目录！！");
            throw new FileException(FileException.FILE_NOT_DIRECTORY);
        }
        return list;
    }

    @Override
    public void uploadFile(MultipartFile file) throws FileNotFoundException {

        String fileName = file.getOriginalFilename();
        String fullName = ZFilenameUtils.concat(root, fileName);

        FileOutputStream fos = new FileOutputStream(fullName);
        try {
            fos.write(file.getBytes());
            fos.flush();
            fos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    public String showDocument(String name) throws FileNotFoundException, IOException {
        logger.debug(name);
        String fullName = ZFilenameUtils.concat(root, name);

        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(fullName));// 构造一个BufferedReader类来读取文件
            String s = null;
            while ((s = br.readLine()) != null) {// 使用readLine方法，一次读一行
                result.append(System.lineSeparator() + s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    @Override
    public void editDocument(String name, String text) throws FileException {
        logger.debug("editDocument:{}", text);
        String fullName = ZFilenameUtils.concat(root, name);
        // FileUtils.
        IOHelper.writeTxtFile(text, new File(fullName));
    }

    @Override
    public SimpleTree getFileTree() throws FileException {
        SimpleTree tree = new SimpleTree("root");
        fileRespository.iteratorPath(root, tree);
        return tree;
    }

    @Override
    public void copyToDir(String name, String targetDir) throws IOException {
        String sourceName = ZFilenameUtils.concat(root, name);
        String targetName = ZFilenameUtils.concat(root, targetDir);

        File source = new File(sourceName);
        File target = new File(targetName);
//		if (!target.exists()) {
//			fileRespository.createDir(target);
//		}
        fileRespository.copyToDir(source, target);


    }

    @Override
    public File getFileByName(String name) {
        String fileName = ZFilenameUtils.concat(root, name);
        return new File(fileName);
    }

}
